/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use std::cell::RefCell;
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;

use anyhow::{anyhow, Result};
use clap::{Args, Parser, Subcommand};
use figment::{
    providers::{Format, Toml},
    Figment,
};
use ini::Ini;

use sophon::prelude::*;

static STORE_PATH: &'static str = ".ini";

#[derive(Parser)]
#[command(name = "sophon")]
#[command(author = "jqiris <1920624985@qq.com>")]
#[command(version = "1.0")]
#[command(about = "build or run sophon micro service", long_about = None)]
#[command(propagate_version = true)]
pub struct MicroApp {
    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Subcommand)]
pub enum Commands {
    /// set or view global params
    Global(GlobalParam),
    /// set or view project params
    Project(ProjectParam),
    ///build the docker image
    Build(ProjectParam),
    ///run the docker image
    Run(ProjectParam),
    ///start the docker container
    Start(ProjectParam),
    ///stop the docker container
    Stop(ProjectParam),
    ///rm the docker container
    Rm(ProjectParam),
    ///rmi the docker image
    Rmi(ProjectParam),
    ///restart the docker service
    Restart(ProjectParam),
    ///clear the docker service
    Clear(ProjectParam),
    ///push image to registry
    Push(ProjectParam),
    ///pull image from registry
    Pull(ProjectParam),
}

#[derive(Subcommand)]
pub enum Registrys {}

#[derive(Debug, Args)]
pub struct GlobalParam {
    #[arg(short, long, help = "The name of the project")]
    pub project: Option<String>,
    #[arg(short, long, help = "The addr of the registry")]
    pub registry: Option<String>,
}

#[derive(Debug, Args, Clone)]
pub struct ProjectParam {
    servers: Option<Vec<String>>,
    #[arg(short, long, help = "exclude servers")]
    excludes: Option<String>,
    #[arg(short, long, help = "set or view app name")]
    app_name: Option<String>,
    #[arg(short, long, help = "set or view author info")]
    author: Option<String>,
    #[arg(short, long, help = "set or view data dir")]
    pub data: Option<String>,
    #[arg(short, long, help = "set or view network")]
    network: Option<String>,
    #[arg(short, long, help = "set or view prefix")]
    prefix: Option<String>,
    #[arg(short, long, help = "set or view version")]
    ver: Option<String>,
    #[arg(short, long, help = "set or view config")]
    config: Option<String>,
    #[arg(long, help = "set or view remote config")]
    remote_config: Option<String>,
    #[arg(long, help = "set or view rust version")]
    rust_version: Option<String>,
    #[arg(long, help = "set or view python version")]
    python_version: Option<String>,
    #[arg(long, help = "set or view alpine version")]
    alpine_version: Option<String>,
    #[arg(long, help = "set or view build path")]
    build_path: Option<String>,
    #[arg(long, help = "set or view build ai")]
    build_ai: bool,
    #[arg(long, help = "set or view build prof")]
    build_prof: bool,
    //run extra params
    #[arg(long, help = "set or view run memory")]
    memory: Option<String>,
    #[arg(long, help = "set or view run memory swap")]
    memory_swap: Option<String>,
    #[arg(long, help = "set or view run kernal memory")]
    kernel_memory: Option<String>,
    #[arg(long, help = "set or view run cpus")]
    cpus: Option<String>,
    #[arg(long, help = "set or view run cpuset-cpus")]
    cpuset_cpus: Option<String>,
}

struct MicroParam<'a> {
    key: &'a str,
    val: &'a str,
}

impl<'a> MicroParam<'a> {
    fn new(key: &'a str, val: &'a str) -> Self {
        Self { key, val }
    }
}

impl MicroApp {
    pub fn global_exec(&self, args: &GlobalParam) {
        let mut conf = Ini::new();
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf = v;
            }
            Err(_) => {
                conf.with_section(Some("global")).set("project", "default");
                conf.write_to_file(STORE_PATH).unwrap();
            }
        }

        let mut set_list = Vec::<MicroParam>::new();
        if let Some(v) = &args.project {
            set_list.push(MicroParam::new("project", v));
        }
        if let Some(v) = &args.registry {
            set_list.push(MicroParam::new("registry", v));
        }
        if set_list.len() > 0 {
            let global_set = conf.section_mut(Some("global")).unwrap();
            for v in set_list {
                global_set.insert(v.key, v.val);
            }
            conf.write_to_file(STORE_PATH).unwrap();
            //打印成功信息
            println!("global set successfully")
        } else {
            let global_read = conf.section(Some("global"));
            if let Some(list) = global_read {
                for (k, v) in list.iter() {
                    println!("global:{}=>{}", k, v);
                }
            } else {
                println!("global:none")
            }
        }
    }

    pub fn project_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global_nmut = conf.borrow();
        let project = global_nmut
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let mut set_list = Vec::<MicroParam>::new();
        if let Some(v) = &args.app_name {
            set_list.push(MicroParam::new("app_name", v));
        }
        if let Some(v) = &args.author {
            set_list.push(MicroParam::new("author", v));
        }
        if let Some(v) = &args.data {
            set_list.push(MicroParam::new("data", v));
        }
        if let Some(v) = &args.network {
            set_list.push(MicroParam::new("network", v));
        }
        if let Some(v) = &args.prefix {
            set_list.push(MicroParam::new("prefix", v));
        }
        if let Some(v) = &args.ver {
            set_list.push(MicroParam::new("ver", v));
        }
        if let Some(v) = &args.config {
            set_list.push(MicroParam::new("config", v));
        }
        if let Some(v) = &args.remote_config {
            set_list.push(MicroParam::new("remote_config", v));
        }
        if let Some(v) = &args.rust_version {
            set_list.push(MicroParam::new("rust_version", v));
        }
        if let Some(v) = &args.alpine_version {
            set_list.push(MicroParam::new("alpine_version", v));
        }
        if let Some(v) = &args.python_version {
            set_list.push(MicroParam::new("python_version", v));
        }
        if let Some(v) = &args.memory {
            set_list.push(MicroParam::new("memory", v));
        }
        if let Some(v) = &args.memory_swap {
            set_list.push(MicroParam::new("memory_swap", v));
        }
        if let Some(v) = &args.kernel_memory {
            set_list.push(MicroParam::new("kernel_memory", v));
        }
        if let Some(v) = &args.cpus {
            set_list.push(MicroParam::new("cpus", v));
        }
        if let Some(v) = &args.cpuset_cpus {
            set_list.push(MicroParam::new("cpuset_cpus", v));
        }
        let global_read = global_nmut.section(Some(project));
        if let None = global_read {
            let ctl = conf.clone();
            let mut global_mut = ctl.borrow_mut();
            global_mut.with_section(Some(project)).set("ver", "v0.0.1");
            global_mut.write_to_file(STORE_PATH).unwrap();
        }
        if set_list.len() > 0 {
            let ctl = conf.clone();
            let mut global_mut = ctl.borrow_mut();
            let global_set = global_mut.section_mut(Some(project)).unwrap();
            for v in set_list {
                global_set.insert(v.key, v.val);
            }
            global_mut.write_to_file(STORE_PATH).unwrap();
            println!("{} set successfully", project)
        } else {
            if let Some(list) = global_read {
                for (k, v) in list.iter() {
                    println!("{}:{}=>{}", project, k, v);
                }
            } else {
                println!("{}:none", project)
            }
        }
    }

    //构建镜像
    pub fn build_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        //构建路径
        let mut build_path = ".".to_string();
        if let Some(p) = params.build_path.clone() {
            build_path = p;
        }
        //构建服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.clone().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the build server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.clone());
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.clone().unwrap();
        let tpl = self.get_docker_template(&params);
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //build server
            match self.build_server(tpl.clone(), &build_path, &prefix, &version, cfg) {
                Ok(output) => {
                    println!("server build result:{}", output);
                }
                Err(err) => {
                    panic!("failed to build server:{}", err);
                }
            }
        }
        println!("server build end");
    }
    //构建服务
    fn build_server(
        &self,
        tpl: String,
        build_path: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        //创建构建文件
        if let Err(err) = self.server_docker_create(tpl, prefix.to_owned(), server) {
            return Err(err);
        }
        //构建镜像
        let file_name = self.server_docker_name(server);
        let args = [
            "build",
            "-f",
            &file_name,
            "--build-arg",
            &format!("run_server={}", server.server_id),
            "--build-arg",
            &format!("client_port={}", server.client_port),
            "-t",
            &self.run_image(prefix.to_owned(), version.to_owned(), server),
            build_path,
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        //清除文件
        self.server_docker_remove(server);
        resp
    }
    //清理服务
    pub fn clear_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the clear server: {}", sid);
                }
            }
        }
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.shut_weight {
                wa = v;
            }
            if let Some(v) = b.shut_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.clear_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server clear result:{}", output);
                }
                Err(err) => {
                    panic!("failed to clear server:{}", err);
                }
            }
        }
        println!("server clear end");
    }
    //清理服务
    fn clear_server(&self, prefix: &str, version: &str, server: &Server) -> Result<String> {
        //stop server
        if let Err(err) = self.stop_server(prefix, version, server) {
            return Err(err);
        }
        //rm server
        if let Err(err) = self.rm_server(prefix, version, server) {
            return Err(err);
        }
        //rmi server
        if let Err(err) = self.rmi_server(prefix, version, server) {
            return Err(err);
        }
        Ok("clear over".to_string())
    }
    //重启镜像
    pub fn restart_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the start server: {}", sid);
                }
            }
        }
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.shut_weight {
                wa = v;
            }
            if let Some(v) = b.shut_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        for cfg in launch_servers.to_owned() {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //stop server
            match self.stop_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server stop result:{}", output);
                }
                Err(err) => {
                    panic!("failed to stop server:{}", err);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.start_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server start result:{}", output);
                }
                Err(err) => {
                    panic!("failed to start server:{}", err);
                }
            }
        }
        println!("server restart end");
    }
    //运行镜像
    pub fn start_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the start server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.start_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server start result:{}", output);
                }
                Err(err) => {
                    panic!("failed to start server:{}", err);
                }
            }
        }
        println!("server start end");
    }
    //开始服务
    fn start_server(&self, prefix: &str, version: &str, server: &Server) -> Result<String> {
        //开始服务
        let args = [
            "start",
            &self.run_name(prefix.to_owned(), version.to_owned(), server),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    //运行镜像
    pub fn stop_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the stop server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.shut_weight {
                wa = v;
            }
            if let Some(v) = b.shut_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.stop_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server stop result:{}", output);
                }
                Err(err) => {
                    panic!("failed to stop server:{}", err);
                }
            }
        }
        println!("server stop end");
    }
    //结束服务
    fn stop_server(&self, prefix: &str, version: &str, server: &Server) -> Result<String> {
        //开始服务
        let args = [
            "stop",
            &self.run_name(prefix.to_owned(), version.to_owned(), server),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    //删除服务
    pub fn rm_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the rm server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.shut_weight {
                wa = v;
            }
            if let Some(v) = b.shut_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.rm_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server rm result:{}", output);
                }
                Err(err) => {
                    panic!("failed to rm server:{}", err);
                }
            }
        }
        println!("server rm end");
    }
    //删除服务
    fn rm_server(&self, prefix: &str, version: &str, server: &Server) -> Result<String> {
        //开始服务
        let args = [
            "rm",
            &self.run_name(prefix.to_owned(), version.to_owned(), server),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    //删除服务
    pub fn rmi_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the rmi server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.shut_weight {
                wa = v;
            }
            if let Some(v) = b.shut_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.rmi_server(&prefix, &version, cfg) {
                Ok(output) => {
                    println!("server rmi result:{}", output);
                }
                Err(err) => {
                    panic!("failed to rmi server:{}", err);
                }
            }
        }
        println!("server rmi end");
    }
    //删除镜像
    fn rmi_server(&self, prefix: &str, version: &str, server: &Server) -> Result<String> {
        //开始服务
        let args = [
            "rmi",
            &self.run_image(prefix.to_owned(), version.to_owned(), server),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    //运行镜像
    pub fn run_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.to_owned().unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the run server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //run server
            match self.run_server(params.to_owned(), cfg) {
                Ok(output) => {
                    println!("server run result:{}", output);
                }
                Err(err) => {
                    panic!("failed to run server:{}", err);
                }
            }
        }
        println!("server run end");
    }
    //构建服务
    fn run_server(&self, params: ProjectParam, server: &Server) -> Result<String> {
        let mut data = String::new();
        if let Some(v) = &params.data {
            data = format!("{}:/data", v);
        }
        let mut network = String::new();
        if let Some(v) = &params.network {
            network = format!("--network={}", v);
        }
        let out_port = format!("{}:{}", server.client_port, server.client_port);
        //运行镜像
        let mut args = vec!["run", "-d", "-v", &data, "-p", &out_port, &network];
        let (memory, memory_swap, kernel_memory);
        if let Some(v) = &params.memory {
            memory = format!("--memory={}", v.to_owned());
            args.push(&memory);
        }
        if let Some(v) = &params.memory_swap {
            memory_swap = format!("--memory-swap={}", v.to_owned());
            args.push(&memory_swap);
        }
        if let Some(v) = &params.kernel_memory {
            kernel_memory = format!("--kernel-memory={}", v.to_owned());
            args.push(&kernel_memory);
        }
        let (cpus, cpuset_cpus);
        if let Some(v) = &params.cpus {
            cpus = format!("--cpus={}", v.to_owned());
            args.push(&cpus);
        }
        if let Some(v) = &params.cpuset_cpus {
            cpuset_cpus = format!("--cpuset-cpus={}", v.to_owned());
            args.push(&cpuset_cpus);
        }
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        let (run_name, run_image) = (
            format!(
                "--name={}",
                self.run_name(prefix.to_owned(), version.to_owned(), server)
            ),
            self.run_image(prefix, version, server),
        );
        args.push(&run_name);
        args.push(&run_image);
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    //获取排除服务器
    fn get_exclude_servers(&self, excludes: Option<String>) -> Vec<String> {
        let mut arr = Vec::new();
        if let Some(v) = excludes {
            arr = v.clone().split(",").map(|x| x.to_string()).collect();
        }
        arr
    }

    //分析参数
    fn parse_params(
        &self,
        args: &ProjectParam,
        ops: Option<&ini::Properties>,
    ) -> Result<ProjectParam> {
        let mut params = ProjectParam {
            servers: args.servers.clone(),
            excludes: args.excludes.clone(),
            app_name: args.app_name.clone(),
            author: args.author.clone(),
            data: args.data.clone(),
            network: args.network.clone(),
            prefix: args.prefix.clone(),
            ver: args.ver.clone(),
            config: args.config.clone(),
            remote_config: args.remote_config.clone(),
            rust_version: args.rust_version.clone(),
            python_version: args.python_version.clone(),
            alpine_version: args.alpine_version.clone(),
            build_path: args.build_path.clone(),
            memory: args.memory.clone(),
            memory_swap: args.memory_swap.clone(),
            kernel_memory: args.kernel_memory.clone(),
            cpus: args.cpus.clone(),
            cpuset_cpus: args.cpuset_cpus.clone(),
            build_ai: args.build_ai,
            build_prof: args.build_prof,
        };
        if let Some(p) = ops {
            if p.contains_key("app_name") {
                if let None = params.app_name {
                    params.app_name = Some(p.get("app_name").unwrap().to_string());
                }
            }
            if p.contains_key("author") {
                if let None = params.author {
                    params.author = Some(p.get("author").unwrap().to_string());
                }
            }
            if p.contains_key("data") {
                if let None = params.data {
                    params.data = Some(p.get("data").unwrap().to_string());
                }
            }
            if p.contains_key("network") {
                if let None = params.network {
                    params.network = Some(p.get("network").unwrap().to_string());
                }
            }
            if p.contains_key("prefix") {
                if let None = params.prefix {
                    params.prefix = Some(p.get("prefix").unwrap().to_string());
                }
            }
            if p.contains_key("ver") {
                if let None = params.ver {
                    params.ver = Some(p.get("ver").unwrap().to_string());
                }
            }
            if p.contains_key("config") {
                if let None = params.config {
                    params.config = Some(p.get("config").unwrap().to_string());
                }
            }
            if p.contains_key("remote_config") {
                if let None = params.remote_config {
                    params.remote_config = Some(p.get("remote_config").unwrap().to_string());
                }
            }
            if p.contains_key("rust_version") {
                if let None = params.rust_version {
                    params.rust_version = Some(p.get("rust_version").unwrap().to_string());
                }
            }
            if p.contains_key("python_version") {
                if let None = params.python_version {
                    params.python_version = Some(p.get("python_version").unwrap().to_string());
                }
            }
            if p.contains_key("alpine_version") {
                if let None = params.alpine_version {
                    params.alpine_version = Some(p.get("alpine_version").unwrap().to_string());
                }
            }
            if p.contains_key("memory") {
                if let None = params.memory {
                    params.memory = Some(p.get("memory").unwrap().to_string());
                }
            }
            if p.contains_key("memory_swap") {
                if let None = params.memory_swap {
                    params.memory_swap = Some(p.get("memory_swap").unwrap().to_string());
                }
            }
            if p.contains_key("kernel_memory") {
                if let None = params.kernel_memory {
                    params.kernel_memory = Some(p.get("kernel_memory").unwrap().to_string());
                }
            }
            if p.contains_key("cpus") {
                if let None = params.cpus {
                    params.cpus = Some(p.get("cpus").unwrap().to_string());
                }
            }
            if p.contains_key("cpuset_cpus") {
                if let None = params.cpuset_cpus {
                    params.cpuset_cpus = Some(p.get("cpuset_cpus").unwrap().to_string());
                }
            }
        }
        //参数检查
        if let None = params.app_name {
            return Err(anyhow!("please set the app name first"));
        }
        if let None = params.author {
            return Err(anyhow!("please set the author first"));
        }
        if let None = params.ver {
            return Err(anyhow!("please set the version first"));
        }
        if let None = params.config {
            return Err(anyhow!("can't find config path"));
        }
        if let None = params.network {
            return Err(anyhow!("not set network"));
        }
        if let None = params.data {
            return Err(anyhow!("can't find data dir"));
        }
        if let None = params.rust_version {
            params.rust_version = Some("1.69.0".to_string());
        }
        if let None = params.python_version {
            params.python_version = Some("3.11.3".to_string());
        }
        if let None = params.alpine_version {
            params.alpine_version = Some("3.17".to_string());
        }
        if let None = params.remote_config {
            params.remote_config = params.config.clone();
        }
        //初始化配置信息
        let dir = params.data.to_owned().unwrap();
        let file = params.config.to_owned().unwrap();
        let cfg_path = Path::new(&dir).join(file);
        let frame = Figment::from(Toml::file(cfg_path.to_str().unwrap())).focus("frame");
        init_frame(frame);
        Ok(params)
    }
    //运行名称
    fn run_name(&self, prefix: String, _ver: String, server: &Server) -> String {
        if prefix.len() > 0 {
            format!("{}_{}", prefix, server.server_id)
        } else {
            server.server_id.to_owned()
        }
    }
    //运行镜像
    fn run_image(&self, prefix: String, ver: String, server: &Server) -> String {
        if prefix.len() > 0 {
            format!("{}_{}:{}", prefix, server.server_id, ver)
        } else {
            format!("{}:{}", server.server_id, ver)
        }
    }
    //远程运行镜像
    fn run_remote_image(
        &self,
        depot: String,
        prefix: String,
        ver: String,
        server: &Server,
    ) -> String {
        format!("{}/{}", depot, self.run_image(prefix, ver, server))
    }
    //服务docker构建文件名称
    fn server_docker_name(&self, server: &Server) -> String {
        format!("{}_dockerFile", server.server_id)
    }
    //获取docker模版
    fn get_docker_template(&self, params: &ProjectParam) -> String {
        let app_name = params.app_name.clone().unwrap();
        let author = params.author.clone().unwrap();
        let rust_version = params.rust_version.clone().unwrap();
        let python_version = params.python_version.clone().unwrap();
        let alpine_version = params.alpine_version.clone().unwrap();
        let remote_config = params.remote_config.clone().unwrap();
        let build_ai = params.build_ai.clone();
        let build_prof = params.build_prof.clone();
        let mut context = format!(
            r#"      
FROM rust:{rust_version}-alpine{alpine_version} AS builder
RUN echo "http://mirrors.aliyun.com/alpine/v{alpine_version}/main/" > /etc/apk/repositories && apk update 
RUN apk add --no-cache -U musl-dev && apk add --no-cache -U libgcc
RUN apk add protobuf protoc openssl-dev perl make
RUN USER=root cargo new {app_name}
WORKDIR /usr/src/{app_name}
COPY .cargo .cargo
COPY vendor vendor
COPY Cargo.toml Cargo.lock ./
COPY ./src src
RUN cargo install --path . --color always

FROM alpine:{alpine_version}
LABEL author="{author}"
ARG run_server
ARG client_port
# 时区控制
ENV TZ Asia/Shanghai
RUN echo "http://mirrors.aliyun.com/alpine/v{alpine_version}/main/" > /etc/apk/repositories \
&& apk update \
&& apk add curl \
&& apk add --no-cache -U libgcc \
&& apk --no-cache add tzdata zeromq \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo '$TZ' > /etc/timezone

ENV run_mode docker
ENV run_server $(run_server)
ENV RUST_BACKTRACE full

COPY --from=builder /usr/local/cargo/bin/{app_name} /app/buildsrv

WORKDIR /app
EXPOSE $(client_port)
VOLUME /data
ENTRYPOINT ["/app/buildsrv", "/data/{remote_config}"]
        "#,
            rust_version = rust_version,
            alpine_version = alpine_version,
            app_name = app_name,
            author = author,
            remote_config = remote_config,
        );
        if build_ai {
            context = format!(
                r#"      
FROM python-rust:{python_version}-{rust_version}-slim AS builder
RUN apt-get update && apt-get -y install pkg-config libssl-dev unzip perl make
COPY protos/protoc-22.3-linux-x86_64.zip protoc-22.3-linux-x86_64.zip
RUN unzip protoc-22.3-linux-x86_64.zip && mv bin/protoc /usr/local/bin/ && cp -r include/ /usr/local/include/
RUN USER=root cargo new {app_name}
WORKDIR /usr/src/{app_name}
COPY .cargo .cargo
COPY vendor vendor
COPY Cargo.toml Cargo.lock ./
COPY ./src src
RUN cargo install --path . --features saki --color always 

FROM python:{python_version}-slim
LABEL author="{author}"
ARG run_server
ARG client_port
# 时区控制
ENV TZ Asia/Shanghai
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list\
    && apt-get update \
    && apt-get -y install curl tzdata\
    && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone
ENV run_mode docker
ENV run_server $(run_server)
ENV RUST_BACKTRACE full

COPY --from=builder /usr/local/cargo/bin/{app_name} /app/buildsrv
WORKDIR /app
EXPOSE $(client_port)
VOLUME /data
ENTRYPOINT ["/data/setup.sh"]
CMD ["/app/buildsrv", "/data/{remote_config}","--features","saki"]
            "#,
                python_version = python_version,
                rust_version = rust_version,
                app_name = app_name,
                author = author,
                remote_config = remote_config,
            );
        }
        if build_prof {
            context = format!(
                r#"      
FROM rust:{rust_version}-alpine{alpine_version} AS builder
RUN echo "http://mirrors.aliyun.com/alpine/v{alpine_version}/main/" > /etc/apk/repositories && apk update 
RUN apk add --no-cache -U musl-dev && apk add --no-cache -U libgcc
RUN apk add protobuf protoc openssl-dev perl make
RUN USER=root cargo new {app_name}
WORKDIR /usr/src/{app_name}
COPY .cargo .cargo
COPY vendor vendor
COPY Cargo.toml Cargo.lock ./
COPY ./src src
RUN cargo install --path . --features prof --color always

FROM alpine:{alpine_version}
LABEL author="{author}"
ARG run_server
ARG client_port
# 时区控制
ENV TZ Asia/Shanghai
RUN echo "http://mirrors.aliyun.com/alpine/v{alpine_version}/main/" > /etc/apk/repositories \
&& apk update \
&& apk add curl \
&& apk add --no-cache -U libgcc \
&& apk --no-cache add tzdata zeromq \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo '$TZ' > /etc/timezone

ENV run_mode docker
ENV run_server $(run_server)
ENV RUST_BACKTRACE full

COPY --from=builder /usr/local/cargo/bin/{app_name} /app/buildsrv

WORKDIR /app
EXPOSE $(client_port)
VOLUME /data
ENTRYPOINT ["/app/buildsrv", "/data/{remote_config}","--features","prof"]
            "#,
                rust_version = rust_version,
                alpine_version = alpine_version,
                app_name = app_name,
                author = author,
                remote_config = remote_config,
            );
        }
        context
    }

    //创建服务器构建文件
    fn server_docker_create(&self, tpl: String, prefix: String, server: &Server) -> Result<()> {
        let mut server_name = format!("server_{}", server.server_id);
        if prefix.len() > 0 {
            server_name = format!("{}_{}", prefix, server.server_id);
        }
        let context = tpl
            .replace("buildsrv", &server_name)
            .replace("(", "{")
            .replace(")", "}");
        let res = match File::create(self.server_docker_name(server)) {
            Ok(mut write_file) => write_file.write(context.as_bytes()),
            Err(err) => Err(err),
        };
        if let Err(err) = res {
            return Err(anyhow!(err.to_string()));
        }
        Ok(())
    }
    //删除服务器构建文件
    fn server_docker_remove(&self, server: &Server) {
        if let Err(err) = fs::remove_file(&self.server_docker_name(server)) {
            eprint!("{}", err);
        }
    }

    //推送镜像
    pub fn push_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let depot = global
            .section(Some("global"))
            .unwrap()
            .get("registry")
            .expect("please set the registry first");
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the push server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //push server
            match self.push_server(depot, &prefix, &version, cfg) {
                Ok(output) => {
                    println!("server push result:{}", output);
                }
                Err(err) => {
                    panic!("failed to push server:{}", err);
                }
            }
        }
        println!("server push end");
    }
    //推送服务
    fn push_server(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        if let Err(err) = self.image_tag(depot, prefix, version, server) {
            return Err(err);
        }
        if let Err(err) = self.image_push(depot, prefix, version, server) {
            return Err(err);
        }
        if let Err(err) = self.image_remote_clear(depot, prefix, version, server) {
            return Err(err);
        }
        Ok("push over".to_string())
    }
    //拉取镜像
    pub fn pull_exec(&self, args: &ProjectParam) {
        let conf = RefCell::new(Ini::new());
        match Ini::load_from_file(STORE_PATH) {
            Ok(v) => {
                conf.replace(v);
            }
            Err(_) => {
                let ctl = conf.clone();
                ctl.borrow_mut()
                    .with_section(Some("global"))
                    .set("project", "default");
                ctl.borrow_mut().write_to_file(STORE_PATH).unwrap();
            }
        }
        let global = conf.borrow();
        let project = global
            .section(Some("global"))
            .unwrap()
            .get("project")
            .unwrap();
        let depot = global
            .section(Some("global"))
            .unwrap()
            .get("registry")
            .expect("please set the registry first");
        let parse_params = self.parse_params(args, global.section(Some(project)));
        if let Err(err) = parse_params {
            eprintln!("parse params error: {}", err);
            return;
        }
        let params = parse_params.unwrap();
        let mut prefix = String::new();
        if let Some(v) = params.prefix.to_owned() {
            prefix = v
        }
        let version = params.ver.unwrap();
        //运行服务列表
        let servers = get_servers_conf();
        let mut launch_servers = Vec::new();
        if let None = params.servers {
            for (_, cfg) in servers.iter() {
                let is_launch = cfg.is_launch.unwrap_or(false);
                if is_launch {
                    launch_servers.push(cfg);
                }
            }
        } else {
            for sid in params.servers.unwrap().iter() {
                if servers.contains_key(sid) {
                    let server = servers.get(sid).unwrap();
                    launch_servers.push(server);
                } else {
                    panic!("can't find the pull server: {}", sid);
                }
            }
        }
        launch_servers.sort_by(|a, b| {
            let (mut wa, mut wb) = (0, 0);
            if let Some(v) = a.launch_weight {
                wa = v;
            }
            if let Some(v) = b.launch_weight {
                wb = v;
            }
            wa.cmp(&wb)
        });
        let excludes = self.get_exclude_servers(params.excludes.to_owned());
        for cfg in launch_servers {
            if excludes.contains(&cfg.server_id) {
                continue;
            }
            //pull server
            match self.pull_server(depot, &prefix, &version, cfg) {
                Ok(output) => {
                    println!("server pull result:{}", output);
                }
                Err(err) => {
                    panic!("failed to pull server:{}", err);
                }
            }
        }
        println!("server pull end");
    }
    //拉取服务
    fn pull_server(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        if let Err(err) = self.image_pull(depot, prefix, version, server) {
            return Err(err);
        }
        if let Err(err) = self.image_untag(depot, prefix, version, server) {
            return Err(err);
        }
        if let Err(err) = self.image_remote_clear(depot, prefix, version, server) {
            return Err(err);
        }
        Ok("pull over".to_string())
    }
    fn image_tag(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        let args = [
            "tag",
            &self.run_image(prefix.to_owned(), version.to_owned(), server),
            &self.run_remote_image(
                depot.to_owned(),
                prefix.to_owned(),
                version.to_owned(),
                server,
            ),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    fn image_push(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        let args = [
            "push",
            &self.run_remote_image(
                depot.to_owned(),
                prefix.to_owned(),
                version.to_owned(),
                server,
            ),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    fn image_pull(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        let args = [
            "pull",
            &self.run_remote_image(
                depot.to_owned(),
                prefix.to_owned(),
                version.to_owned(),
                server,
            ),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    fn image_untag(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        let args = [
            "tag",
            &self.run_remote_image(
                depot.to_owned(),
                prefix.to_owned(),
                version.to_owned(),
                server,
            ),
            &self.run_image(prefix.to_owned(), version.to_owned(), server),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
    fn image_remote_clear(
        &self,
        depot: &str,
        prefix: &str,
        version: &str,
        server: &Server,
    ) -> Result<String> {
        let args = [
            "rmi",
            &self.run_remote_image(
                depot.to_owned(),
                prefix.to_owned(),
                version.to_owned(),
                server,
            ),
        ];
        let resp = match Command::new("docker").args(args).spawn() {
            Ok(child) => match child.wait_with_output() {
                Ok(v) => Ok(String::from_utf8(v.stdout).unwrap()),
                Err(err) => Err(anyhow!(err)),
            },
            Err(err) => Err(anyhow!(err)),
        };
        resp
    }
}
